/*  ----------------------------------------------------------------------------
 *  Arello Mobile
 *  Fast 3d Engine
 *  ----------------------------------------------------------------------------
 * Except where otherwise noted, this work is licensed under
 * http://creativecommons.org/licenses/by/3.0
 */

#ifndef __LIB2D_NODE_NODE_H__
#define __LIB2D_NODE_NODE_H__

#include "NodeBase.h"
//#include <lib3d/CameraDesc.h>
//#include <lib3d/hard/RenderList.h>
//#include <filesystem/String.hpp>
#include <NoCopy.h>
#include <list>


namespace liba
{
namespace lib2d
{

namespace hard { class Renderer; }

namespace node
{

class Root;

class Node :
	public NodeBase,
	private Nocopy
{
public:
	typedef std::list<Node *> Children;
	static const Atom node_name;

	//Attributes
	static const Atom visibility_name;

	Node( const Atom & name, Node * parent );
	virtual ~Node();

	using NodeBase::change_attribute;
	using NodeBase::get_attribute;

	virtual bool change_attribute( const Atom & name, double value );
	virtual bool get_attribute( const Atom & name, double * value )const;

	virtual animate::Node * find_animate_node( const Atom & name, bool recursion );
	Node * find_node( const Atom & name, bool recursion );
	void clear();

	virtual bool render( hard::Renderer * hardware );//, const CameraDesc & camera_desc );
//	virtual void render_to_list( hard::Hardware * hardware, hard::RenderList * render_list );

	Node * get_parent()const;

	virtual Root * get_root();
	void add_child( Node * node, bool change_world_pos = false );

///	Matrix get_full_matrix()const;

	void change_visibility( bool visible );
	bool get_visibility()const;

	using NodeBase::change_rotation;
//	void change_rotation( const Vector & target_pos, const Vector & top );
protected:
	virtual bool on_attribute( xml::Provider * prov, const String & name, const String & value );
	virtual bool on_node( xml::Provider * prov, const String & name );

	bool visibility;

	Node * parent;
	Children children;
	Children::iterator pos_in_parent;

///	void set_full_matrix( const Matrix & mat );
};

inline Node * Node::get_parent()const
{
	return parent;
}

inline Root * Node::get_root()
{
	return parent->get_root();
}

inline void Node::change_visibility( bool visible )
{
	visibility = visible;
}

inline bool Node::get_visibility()const
{
	return visibility;
}

//Node * create_from_resource( const Atom & name, Node * parent, const filesystem::String & resource_name );

} // namespace node
} // namespace lib2d
} // namespace liba
using namespace liba;

#endif //__LIB2D_NODE_NODE_H__

